<?php
/**
 * 天气流程：有请求时先分解出参数，再从 apc 缓存中读取相应的数据，如果apc中对应的城市不在则重新从网络获取，获取完成后更新天气更新数量表
 * 节日信息：直接获取
 *
 * 使用格式：http://w.mdeve.com/{cityid}.(ics|gics|xml|wcc), rewrite后为 /create.php?id={id}&hash={hash}
 * cityid  查询方式：拼音、城市代码
 */

require 'runtime.php';
$cache_time = 1800;			// 服务器缓存时间，单位秒
$argc = filter_input(INPUT_GET, "id");
$hash = filter_input(INPUT_GET, "hash");
/////////////////////////////////////////////////////////////////////////////
// 过滤掉老的参数
if(strpos($argc, "!") !== false){
	$arr = explode("!", $argc);
	$argc = $arr[1];
}
/////////////////////////////////////////////////////////////////////////////
if(false === strpos($argc, ",")) $argc .= ",1";
list($cityid, $parameter_id) = explode(",", $argc);
$parameter_id = intval($parameter_id);
if(!$parameter_id) $parameter_id = 1;
// 检测是否有相应的接口
$interface_file = 'interface/class.' . $hash . '.php';
if(!file_exists($interface_file)) exit("Interface not found!");

// 处理城市代码
//if(is_numeric($cityid) && strlen($cityid)==9){}	// 此为城市代码，不做处理
// 过滤掉不符合规定的城市代码
if(strpos($cityid, "%")!==false) exit("err:01");
if(is_numeric($cityid) && strlen($cityid)!=9) exit("err:02");	// 为数字但不为城市ID，可能是区号查询，过滤掉。
if(strlen($cityid)>20) exit("err:03");

// 如果不是城市ID，判断是否为农历模式
$mode = "weather";
if(!is_numeric($cityid) || strlen($cityid) != 9){
	$n1 = substr($cityid, 0, 1);
	$n2 = substr($cityid, 1);
	if($n1 == "n" && is_numeric($n2)){		// 纯农历模式
		$mode = "lunar";
		$parameter_id = $n2;
		$cityid = "n". $n2;
	}
}

// 获取样式
$style = array();
$db = init_db();
$db->startTrans();
if($cache->exists("weather:parameter:". $parameter_id)){
	$style = $cache->fetch("weather:parameter:". $parameter_id);
}else{
	$style = $db->get_row("select * from weather_parameter where id={$parameter_id}");
	if(false === $style) exit("err:04");		// 如果没有找到相应的参数
	$cache->store("weather:parameter:". $parameter_id, $style);
}

// 如果设置中不显示天气，则强制为日历模式
if($style["show_weather"]==0 && $style["show_festival"]==0) exit("Parameter error");
if($style["show_weather"]==0) $mode = "lunar";
/*
 * 天气样式更新
* 天气显示天数为 1-15，如果不在此范围强制设置为7
* 农历显示以前天数为0-90，不在此范围强制设置为0
* 农历显示以后天数为1-365，不在此范围强制设置成7
*/
if($style["weather_days"]<1 || $style["weather_days"]>15) $style["weather_days"] = 7;
if($style["festival_before_days"]<0 || $style["festival_before_days"]>90) $style["weather_days"] = 0;
if($style["festival_later_days"]<1 || $style["festival_later_days"]>365) $style["festival_later_days"] = 7;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 天气模式开始
if($mode == "weather"){

	// 获取天气，如果天气是拼音将拼音转换成城市ID
	if(!is_numeric($cityid) || strlen($cityid) != 9){
		$cityid = strtolower($cityid);
		// 从天气ID数据库获取天气ID
		require 'library/defined.cityid.php';
		if(array_key_exists($cityid, $CITYID)) {
			$cityid = $CITYID[$cityid];
		}
	}
	// 如果转换后还不是城市ID则出错。
	$focus_update = false;		// 是否需要强制更新

	// 城市代码处理
	//if(!is_numeric($cityid) || strlen($cityid) != 9) exit("err:05");
	// 9位纯数字城市ID，12位最后为大写的A为风景区
	if(!strlen($cityid)!=9 && !strlen($cityid)==12)  exit("err:05");
	if(strlen($cityid)==9 && !is_numeric($cityid)) exit("err:05a");
	if(strlen($cityid)==12 && !substr($cityid, -1)=="a") exit("err:05b");
	if(strlen($cityid)==12) $cityid = strtoupper($cityid);

	// 读取天气数据，如果数据库中没有此数据则增加一条
	$weather_data_in_database = $db->get_row("select * from weather_data where cityid='{$cityid}'");
	if(false===$weather_data_in_database){
		// 如果数据库中没有缓存的数据，则增加一条缓存记录，并强制更新天气
		$db->execute("insert into weather_data(cityid) values('{$cityid}')");
		$focus_update = true;
	}else{
		// 如果有记录，并且缓存时间大于指定缓存时间，则强制更新天气
		if(time() - strtotime($weather_data_in_database["lastupdate"]) > $cache_time) $focus_update = true;
	}


	$bytes_update = 0;		// 本次更新流量
	$bytes_grab = 0;		// 本次抓取流量
	$weather_data = array();		// 本次的天气信息

	//$focus_update = true;		// 强制更新，测试时用

	if(!$focus_update){
		// 如果不是强制更新
		$weather_data = unserialize(base64_decode($weather_data_in_database["data"]));
		$weather_data["lastupdate"] = $weather_data_in_database["lastupdate"];
	}else{
		// 如果是强制更新
		// 从apc缓存中获取分流服务器列表，如果没有则创建
		$shunt_server = array();
		if($cache->exists("weather:server")){
			$shunt_server = $cache->fetch("weather:server");
		}else{
			$shunt_server = $db->get_rows("select id,server,weights,content from weather_server where hidden=0");
			if(false === $shunt_server) exit("err:06");
			$cache->store("weather:server", $shunt_server);
		}

		// 开始从分流服务器更新，如果分流服务器挂了则重新搜索可用服务器，直到搜到能用为止
		$ex_arr = array(-1);
		try{
			// 如果分流服务器挂了则重新搜索可用服务器，直到搜到能用为止
			for($x=0;$x<sizeof($shunt_server);$x++){
				$i = get_randnum($shunt_server, $ex_arr);
				//print_r($shunt_server[$i]);exit;
				$url = str_replace("{action}", $cityid, $shunt_server[$i]['server']);
				$s = get_file($url);
				if(strlen($s)<128){
					$ex_arr[] = $i;
				}else{
					break;
				}
			}

			$bytes_update = strlen($s);
			$s = base64_decode($s);
			if(strlen($s)<33) die ("Server ".$shunt_server[$i]["id"]." read {$cityid} error!<br />");
			$s = substr($s,0,strlen($s)-32);
			$s = @gzuncompress($s);
			if(strlen($s)<33) die ("Server ".$shunt_server[$i]["id"]." read {$cityid} error!!<br />");
			$weather_data = unserialize($s);
			$weather_data["lastupdate"] = date("Y-m-d H:i:s");	// 如果是刚刚更新，则增加最后更新时间
			unset($s);
			$bytes_grab = $weather_data["in_flow"];
			// 更新完成后修改服务器更新量
			$server_id = $shunt_server[$i]["id"];
		}catch(PDOException $e){
			die ("Server {$i} read error!<br /><br />" . $e->getMessage() . "<br />");
		}

		// 读取PM2.5状况
		/*
		$AQI = $db->get_row("select * from weather_aqi where cityid='{$cityid}'");
		if(false!==$AQI){
			$AQI["detail"] = base64_decode(unserialize($AQI["detail"]));
			$weather_data["AQI"] = $AQI;
		}
		*/

		// 更新到服务器
		$db->query("update weather_server set num=num+1,lastupdate='".date("Y-m-d H:i:s")."',bytes_grab=bytes_grab+".$bytes_grab.",bytes_update=bytes_update+".$bytes_update.",lastcity='". ($weather_data["city_1"]=="城区" ? $weather_data["city_2"] : $weather_data["city_1"]). "' where id={$server_id}");
		// 更新记录
		$db->query("insert into weather_history(server,citycode,city,lastupdate,type) values('".$shunt_server[$i]['content']."','{$cityid}','". ($weather_data["city_1"]=="城区" ? $weather_data["city_2"] : $weather_data["city_1"]). "',now(),'{$hash}')");
		// 将天气更新数据写入天气缓存库
		$db->execute("update weather_data set province='$weather_data[city_3]', city='". ($weather_data["city_1"]=="城区" ? $weather_data["city_2"] : $weather_data["city_1"]). "', data='".base64_encode(serialize($weather_data))."', lastupdate='".date("Y-m-d H:i:s")."' where cityid='{$cityid}'");

	}

	// 将天气同步数据写入天气缓存库
	$db->execute("update weather_data set lastsync='".date("Y-m-d H:i:s")."',`type`='{$hash}', num=num+1 where cityid='{$cityid}'");
	// 将数据写入更新统计表
	$rs = $db->query("select id from weather_count where `table`='{$hash}' and `date`='".date("Y-m-d")."' and `hour`=".date("H"));
	if($rs->rowCount()){
		$db->query("update weather_count set `nums`=`nums`+1 where `table`='{$hash}' and `date`='".date("Y-m-d")."' and `hour`=".date("H"));
	}else{
		$db->query("insert into weather_count(`table`,`date`,`hour`,`nums`) values('{$hash}','".date("Y-m-d")."','".date("H")."',1)");
	}
	// 将数据更新到样式表
	if($hash == "ics"){
		$db->query("update `weather_parameter` set lastsync='".date("Y-m-d H:i:s")."', num=num+1 where id={$parameter_id}");
	}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}else{	// 纯农历模式
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	$hash = "lunar";
	$weather_data = array();
	$bytes_grab = 0;
	$bytes_update = 0;
	$interface_file = 'interface/class.lunar.php';
	$db->query("update `weather_parameter` set lastsync='".date("Y-m-d H:i:s")."', num=num+1 where id={$parameter_id}");
	// 将数据写入更新统计表
	$rs = $db->query("select id from weather_count where `table`='{$hash}' and `date`='".date("Y-m-d")."' and `hour`=".date("H"));
	if($rs->rowCount()){
		$db->query("update weather_count set `nums`=`nums`+1 where `table`='{$hash}' and `date`='".date("Y-m-d")."' and `hour`=".date("H"));
	}else{
		$db->query("insert into weather_count(`table`,`date`,`hour`,`nums`) values('{$hash}','".date("Y-m-d")."','".date("H")."',1)");
	}
	// 更新记录
	$db->query("insert into weather_history(server,citycode,city,lastupdate,type) values('农历模式','{$cityid}','all',now(),'{$hash}')");
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}



// 到此天气数据已获取完成
require 'interface/abstract.php';
require $interface_file;
$interface = new _interface();
$interface->cityid = $cityid;
$interface->db = $db;
$interface->weather_data = $weather_data;
$interface->bytes_grab = $bytes_grab;
$interface->bytes_update = $bytes_update;
$interface->bytes_sync = 0;
$interface->style = $style;

$interface->dispose_data();
$db->commit();









